﻿using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Xml;
using System.Xml.Schema;

namespace LetiLib.Utils
{
    // LedValidator as Singleton class
    public sealed class LedValidator
    {
        LedValidator()
        {
        }

        public static LedValidator Instance
        {
            get
            {
                return XmlLedValidator.instance;
            }
        }

        class XmlLedValidator
        {
            // Explicit static constructor to tell C# compiler
            // not to mark type as beforefieldinit
            static XmlLedValidator()
            {
            }

            internal static readonly LedValidator instance = new LedValidator();

            int ErrorsCount = 0;
            string ErrorsMessage = "";
            const string XSD_PATH = "LedCenter.xsd";

            XmlTextReader tr = null;
            XmlSchemaCollection xsc = null;
            XmlValidatingReader vr = null;

            public void ValidationHandler(object sender, ValidationEventArgs args)
            {
                ErrorsMessage += args.Message + "\r\n";
                ErrorsCount++;
            }

            public void ValidateElement(string xmlString)
            {
                try
                {

                    if (tr == null)
                        tr = new XmlTextReader(XSD_PATH);
                    if (xsc == null)
                    {
                        xsc = new XmlSchemaCollection();
                        xsc.Add(null, tr);
                    }

                    //if (vr == null)
                    {
                        vr = new XmlValidatingReader(xmlString, XmlNodeType.Element, null);

                        vr.Schemas.Add(xsc);

                        // validation event handler
                        vr.ValidationType = ValidationType.Schema;
                        vr.ValidationEventHandler += new ValidationEventHandler(ValidationHandler);
                    }
                    // validate xml data
                    while (vr.Read()) ;

                    vr.Close();

                    // Raise exception if validation fails
                    if (ErrorsCount > 0)
                    {
                        throw new Exception(ErrorsMessage);
                    }

                    // validation success 
                    Debug.WriteLine("Validation success");
                }
                catch (Exception e)
                {
                    Debug.WriteLine("Xml validation failed \r\nError message: " + e.Message);
                }
            }
        }
    }
}
